extends Control
class_name PopupMenuBase
 
@export var menuItemWidth = 30
@export var menuItemHeight = 8

var containerArr:Array = []
var containerDict:Dictionary = {}
var containerPosDict:Dictionary = {}
var containerDepthDict:Dictionary = {}

var showPos

signal sigClickMenuItem
signal sigCancelPopup


func initAndShow(menuItems:Array, showPos):
	containerDepthDict = {}
	containerArr = []
	containerDict = {}
	
	initMenuItems(menuItems, 0, "topMost")
	initContainersPos(showPos)
	
	containerDict["topMost"].showAll()
	containerDepthDict[0] = containerDict["topMost"]
	
	set_physics_process(true)
	

func initMenuItems(menuItemsData:Array, depth, parentMenuItemName):
	var container = Global.createSceneInst(Consts.RESOURCE_UI_POPUP_CONTAINER)
	add_child(container)
	container.commandBox = self
	containerArr.append(container)
	containerDict[parentMenuItemName] = container
	container.init(menuItemsData, depth, parentMenuItemName)
	container.hideAll()
	
	for menuItemData in menuItemsData:
		if menuItemData.subMenuItemsData.size() > 0:
			initMenuItems(menuItemData.subMenuItemsData, depth + 1, menuItemData.name)
			
			
func initContainersPos(pos):
	showPos = pos
	containerPosDict = {}
	
	var isRight = true
	for container in containerArr:
		var tentativeTargetPosX = showPos.x + container.depth * (container.containerSize.x + 1)
		var tentativeTargetPosY = showPos.y
		var withinViewX = isWithinViewX(Vector2(tentativeTargetPosX + container.containerSize.x, tentativeTargetPosY))
		if not withinViewX:
			isRight = false
			break
	
	for container in containerArr:
		var tentativeTargetPosX = showPos.x + container.depth * (container.containerSize.x + 1)
		var tentativeTargetPosY = showPos.y
		if not isRight:
			tentativeTargetPosX = showPos.x - (container.depth + 1) * (container.containerSize.x + 1)
		
		var viewPos = Vector2(tentativeTargetPosX, tentativeTargetPosY)
		if viewPos.y < 0:
			tentativeTargetPosY -= viewPos.y
			
		viewPos = Vector2(tentativeTargetPosX, tentativeTargetPosY + container.containerSize.y)
		if viewPos.y >= Global.viewportHeight:
			tentativeTargetPosY -= (viewPos.y - Global.viewportHeight)
		
		containerPosDict[container] = Vector2(tentativeTargetPosX, tentativeTargetPosY)
		container.position = containerPosDict[container]
		

func isWithinViewX(viewPos):
	if viewPos.x >= Global.viewportWidth or viewPos.x < 0:
		return false
	return true


func onMenuItemClick(inst):
	if inst.hasSubMenuitem():
		var targetContainer = containerDict[inst.data.name]
		var depth = targetContainer.depth
		
		if containerDepthDict.has(depth):
			containerDepthDict[depth].hideAll()
			containerDepthDict.erase(depth)
		
		targetContainer.showAll()
		containerDepthDict[depth] = targetContainer
	else:
		print("click menuitem ", inst.data.name)
		if sigClickMenuItem:
			sigClickMenuItem.emit(inst.data.name, inst.data)
		hideAllContainer()

	
func _physics_process(delta):
	processCancel()
	

func hideAllContainer():
	var depth = 3
	for index in range(depth, -1, -1):
		if not containerDepthDict.has(index): continue
		
		containerDepthDict[index].hideAll()
		containerDepthDict.erase(index)
		
	set_physics_process(false)
	
	self.queue_free()


func processCancel():
	if Input.is_action_just_pressed("mouse_right_button"):
		var depth = 3
		for index in range(depth, -1, -1):
			if not containerDepthDict.has(index): continue
			
			containerDepthDict[index].hideAll()
			containerDepthDict.erase(index)
			
			if index == 0:
				set_physics_process(false)
				onCancelPopup()
			
			break
			

func onCancelPopup():
	if sigCancelPopup:
		sigCancelPopup.emit()
	
	self.queue_free()






